package com.psak.cudaphrasal.server.result;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;

import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.ObjectMessage;

import org.apache.log4j.Logger;

import com.psak.cudaphrasal.model.ProcessingResult;
import com.psak.cudaphrasal.server.service.result.ResultManagementService;

/**
 * Listener nasluchujacy na przychodzace wiadomosci o wyniakch przetwarzania
 * 
 * @author piotrs10
 * 
 */
public class ResultMessageListener implements MessageListener {

	private static final Logger LOG = Logger
			.getLogger(ResultMessageListener.class);
	private ResultManagementService resultManagementService;

	@Override
	public void onMessage(Message message) {
		if (message instanceof ObjectMessage) {
			ObjectMessage msg = (ObjectMessage) message;
			try {
				Serializable object = msg.getObject();
				if (object instanceof ProcessingResult) {
					ProcessingResult result = (ProcessingResult) object;
					resultManagementService.mergeAndAddResults(result
							.getPhrasalResults());
					Map<String, Long> results = resultManagementService
							.decodeResults();
					printResults(results);
				}
			} catch (JMSException e) {
				LOG.error("Blad kolejki", e);
			}
		}
	}

	private void printResults(Map<String, Long> results) {
		List<PrintableResult> printableResults = new ArrayList<PrintableResult>();
		System.out.println("Wyniki przetwarzania");
		for (Map.Entry<String, Long> resultEntry : results.entrySet()) {
			printableResults.add(new PrintableResult(resultEntry.getKey(),
					resultEntry.getValue()));
		}
		Collections.sort(printableResults, new Comparator<PrintableResult>() {

			@Override
			public int compare(PrintableResult o1, PrintableResult o2) {
				if (o1.getNumberOfOccurences() > o2.getNumberOfOccurences()) {
					return -1;
				} else if (o1.getNumberOfOccurences() < o2
						.getNumberOfOccurences()) {
					return 1;
				} else {
					return 0;
				}
			}
		});
		for (PrintableResult result : printableResults) {
			result.print();
		}
	}

	public void setResultManagementService(
			ResultManagementService resultManagementService) {
		this.resultManagementService = resultManagementService;
	}

	private class PrintableResult {
		private String phrasal;
		private Long numberOfOccurences;

		public PrintableResult(String phrasal, Long numberOfOccurences) {
			super();
			this.phrasal = phrasal;
			this.numberOfOccurences = numberOfOccurences;
		}

		public String getPhrasal() {
			return phrasal;
		}

		public void setPhrasal(String phrasal) {
			this.phrasal = phrasal;
		}

		public Long getNumberOfOccurences() {
			return numberOfOccurences;
		}

		public void setNumberOfOccurences(Long numberOfOccurences) {
			this.numberOfOccurences = numberOfOccurences;
		}

		public void print() {
			System.out.printf("Zwiazek %s, liczba wystapien %d\n", phrasal,
					numberOfOccurences);
		}
	}

}
